const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const cors = require('koa-cors');
const compress = require('koa-compress');
const { testConnection } = require('./config/db');

// 导入路由
const userRouter = require('./routes/user');
const chatHistoryRouter = require('./routes/chatHistory');
const rolesRouter = require('./routes/roles');
const groupsRouter = require('./routes/groups');
const aiRouter = require('./ai.js');


// 创建应用实例
const app = new Koa();

// 配置压缩中间件
app.use(compress());

// 配置跨域中间件
app.use(cors({
  origin: '*', // 允许所有来源
  allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], // 允许的HTTP方法
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'], // 允许的请求头
  exposeHeaders: ['Content-Length', 'Date', 'X-Request-Id'], // 允许浏览器访问的响应头
  maxAge: 86400, // 预检请求的有效期，单位秒
  credentials: true // 允许发送cookie
}));

// 错误处理中间件
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    console.error('服务器错误', err);
    ctx.status = err.status || 500;
    ctx.body = {
      code: ctx.status,
      message: err.message || '服务器内部错误'
    };
    ctx.app.emit('error', err, ctx);
  }
});

// 请求日志中间件
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});

// 请求体解析
app.use(bodyParser({
  enableTypes: ['json', 'form', 'text'],
  jsonLimit: '10mb'
}));

// 注册AI路由
app.use(aiRouter.routes()).use(aiRouter.allowedMethods());

// 仅对/api开头的路由限制为POST方法
app.use(async (ctx, next) => {
  if (ctx.path.startsWith('/api') && ctx.method !== 'POST') {
    ctx.status = 405;
    ctx.body = {
      code: 405,
      message: '方法不允许，请使用POST方法'
    };
    return;
  }
  await next();
});

// 注册其他路由
app.use(userRouter.routes()).use(userRouter.allowedMethods());
app.use(chatHistoryRouter.routes()).use(chatHistoryRouter.allowedMethods());
app.use(rolesRouter.routes()).use(rolesRouter.allowedMethods());
app.use(groupsRouter.routes()).use(groupsRouter.allowedMethods());

// 未找到路由处理
app.use(async (ctx) => {
  ctx.status = 404;
  ctx.body = {
    code: 404,
    message: '未找到该接口'
  };
});

// 错误事件监听
app.on('error', (err, ctx) => {
  console.error('服务器错误', err);
});

// 启动服务
const PORT = process.env.PORT || 3000;

// 测试数据库连接后启动服务器
(async () => {
  const connected = await testConnection();
  if (connected) {
    app.listen(PORT, () => {
      console.log(`服务已启动，端口 ${PORT}`);
    });
  } else {
    console.error('无法连接到数据库，服务未启动');
    process.exit(1);
  }
})();

module.exports = app; 